$this->client->setLogger( $logger );
}
- /**
- * @param string $key
- * @param int $flags Bitfield of BagOStuff::READ_* constants [optional]
- * @return mixed Returns false on failure and if the item does not exist
- */
- protected function doGet( $key, $flags = 0 ) {
+ protected function doGet( $key, $flags = 0, &$casToken = null ) {
+ $casToken = null;
+
$req = [
'method' => 'GET',
'url' => $this->url . rawurlencode( $key ),
list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $this->client->run( $req );
if ( $rcode === 200 ) {
if ( is_string( $rbody ) ) {
- return unserialize( $rbody );
+ $value = unserialize( $rbody );
+ /// @FIXME: use some kind of hash or UUID header as CAS token
+ $casToken = ( $value !== false ) ? $rbody : null;
+
+ return $value;
}
return false;
}
return false;
}
- /**
- * Handle storage error
- * @param string $msg Error message
- * @param int $rcode Error code from client
- * @param string $rerr Error message from client
- * @return false
- */
- protected function handleError( $msg, $rcode, $rerr ) {
- $this->logger->error( "$msg : ({code}) {error}", [
- 'code' => $rcode,
- 'error' => $rerr
- ] );
- $this->setLastError( $rcode === 0 ? self::ERR_UNREACHABLE : self::ERR_UNEXPECTED );
- return false;
- }
-
public function set( $key, $value, $exptime = 0, $flags = 0 ) {
// @TODO: respect WRITE_SYNC (e.g. EACH_QUORUM)
+ // @TODO: respect $exptime
$req = [
'method' => 'PUT',
'url' => $this->url . rawurlencode( $key ),
return $this->handleError( "Failed to store $key", $rcode, $rerr );
}
+ public function add( $key, $value, $exptime = 0, $flags = 0 ) {
+ // @TODO: make this atomic
+ if ( $this->get( $key ) === false ) {
+ return $this->set( $key, $value, $exptime, $flags );
+ }
+
+ return false; // key already set
+ }
+
public function delete( $key, $flags = 0 ) {
// @TODO: respect WRITE_SYNC (e.g. EACH_QUORUM)
$req = [
}
return $this->handleError( "Failed to delete $key", $rcode, $rerr );
}
+
+ public function incr( $key, $value = 1 ) {
+ // @TODO: make this atomic
+ $n = $this->get( $key, self::READ_LATEST );
+ if ( $this->isInteger( $n ) ) { // key exists?
+ $n = max( $n + intval( $value ), 0 );
+ // @TODO: respect $exptime
+ return $this->set( $key, $n ) ? $n : false;
+ }
+
+ return false;
+ }
+
+ /**
+ * Handle storage error
+ * @param string $msg Error message
+ * @param int $rcode Error code from client
+ * @param string $rerr Error message from client
+ * @return false
+ */
+ protected function handleError( $msg, $rcode, $rerr ) {
+ $this->logger->error( "$msg : ({code}) {error}", [
+ 'code' => $rcode,
+ 'error' => $rerr
+ ] );
+ $this->setLastError( $rcode === 0 ? self::ERR_UNREACHABLE : self::ERR_UNEXPECTED );
+ return false;
+ }
}